﻿//-----------------------------------------------------------------------
// <copyright file="ExplorerIconManager.cs" author="Artak Mkrtchyan">
//     Creative Commons - GNU General Public License (http://creativecommons.org/licenses/GPL/2.0/
// </copyright>
// <author>Artak Mkrtchyan</author>
// <email>mkArtak@gmail.com</email>
// <date>11/02/2013</date>
//-----------------------------------------------------------------------

using ConsoleHoster.Common.Utilities;
using ConsoleHoster.Model.Entities;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Windows.Media;

namespace ConsoleHoster.Utilities
{
	public sealed class ExplorerIconManager : IExplorerItemIconProvider
	{
		private readonly IDictionary<string, ImageSource> iconCache = new ConcurrentDictionary<string, ImageSource>();
		private readonly ILogger logger;
		private readonly IExplorerItemIconProvider iconProvider;

		public ExplorerIconManager(IExplorerItemIconProvider argIconProvider)
			: this(argIconProvider, null)
		{
		}

		public ExplorerIconManager(IExplorerItemIconProvider argIconProvider, ILogger argLogger)
		{
			ValidationManager.RequireArgumentNotNull(argIconProvider, "argIconProvider");

			this.iconProvider = argIconProvider;
			this.logger = new ComponentLogger("ExplorerIconManager", argLogger);
		}

		public ImageSource GetIcon(ExplorerItem argExplorerItem)
		{
			ValidationManager.RequireArgumentNotNull(argExplorerItem, "argExplorerItem");

			string tmpExtension = argExplorerItem.ItemType == ExplorerItemType.Drive ? "[drive]" : argExplorerItem.ItemType == ExplorerItemType.Folder ? "[folder]" : Path.GetExtension(argExplorerItem.Path).ToLower();

			ImageSource tmpResult = null;
			if (!this.iconCache.TryGetValue(tmpExtension, out tmpResult))
			{
				try
				{
					tmpResult = this.iconProvider.GetIcon(argExplorerItem);

					// Not caching drive images as there are only few, and they potentially can have different icons
					if (argExplorerItem.ItemType != ExplorerItemType.Drive)
					{
						this.iconCache.Add(tmpExtension, tmpResult);
					}
				}
				catch (Exception ex)
				{
					this.logger.LogError("Failed to retrieve icon for explorer item: {0}. Details: {1}", argExplorerItem.Path, ex.ToString());
					throw;
				}
			}

			return tmpResult;
		}
	}
}
